﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using RTracker.Models.Common;
using RTracker.Models.Login;
using RTracker.Models.User;
using RTracker.Models.Organization;

namespace RTracker.Controllers
{
    public class LoginController : AppBaseController
    {
        //
        // GET: /Login/

        public ActionResult Index()
        {
            return View();
        }



        /// <summary>
        /// function to log in user.
        /// in this first we check if user is already loggin in same browser.
        /// then we call data layer function to validate login credentails. if true then we check if this user is loggedin at some other place.
        /// if user is logged at othr place then we set the details of status and return it.
        /// after that we check if there is any need to change password before login if true then we get password policy, set the details of status and return status with password policy.
        /// Note:- password policy will be returned olny if there is need to change password.
        /// after that we create entry of this user in session table and set the values in session objects and return with true status.
        /// </summary>
        /// <param name="pstrUserName">username entered by user for login</param>
        /// <param name="pstrPassword">Password entered by user for login</param>
        /// <returns>returns status object with message and password policy in case of change password.</returns>
        [HttpPost]
        public ActionResult Login(string pstrUserName, string pstrPassword)
        {
            CStatus oCStatus = new CStatus();
            try
            {
                MLogin objMLogin = new MLogin();
                CUser oUser = new CUser();
                //set params in CUser model to validate login
                oUser.LogonName = pstrUserName;
                oUser.LogonPassword = pstrPassword;
                oCStatus = objMLogin.ValidateUser(AuthenticationContext, ref oUser);
                //check if status is true means user loggin credentials are ok then check for its 
                //already login state and change for for password if any.
                //else return false status.
                if (oCStatus.Success)
                {
                    CUserSession objCUserSession = new CUserSession();
                    objCUserSession.UserId = oUser.UserId;
                    objCUserSession.OrganizationId = oUser.OrganizationId;

                    MUserSession objMUserSession = new MUserSession();

                    CStatus objSessionStatus = objMUserSession.CreateUserSession(AuthenticationContext, ref objCUserSession);

                    //check if status is true then add entry in application list else set return status .
                    if (objSessionStatus.Success)
                    {
                        // set user logon name and lastaction time in session object.
                        objCUserSession.UserName = oUser.LogonName;
                        objCUserSession.LastActionTime = DateTime.Now.ToString();
                        //store Current user session in session
                        CurrentUserSession = objCUserSession;
                        //create authentication object with ession key
                        AuthenticationContext = new CAuthenticationContext() { UserId = oUser.UserId, SessionKey = objCUserSession.SessionKey };
                        //create entry in application level list.
                        List<CUserSession> lstLoggedinUsers = ApplicationUsers;
                        lstLoggedinUsers.Add(objCUserSession);
                        //set updated list in application level variable.
                        ApplicationUsers = lstLoggedinUsers;

                        //gets all the users in the application user list
                        //GetAllApplicationUsers();

                        
                    }
                    else
                    {
                        oCStatus = objSessionStatus;
                    }
                }
            }
            catch (Exception ex)
            {
                oCStatus.Success = false;
                oCStatus.StatusDetails = ex.Message;
            }
            return Json(new { oCStatus });
        }



        /// <summary>
        /// this function is used to change password of valid user.
        /// </summary>
        /// <param name="pOldPassword">old password entered by user to validate it</param>
        /// <param name="pNewPassword">new password entered by user to change it.</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult ChangePassword(string pOldPassword, string pNewPassword)
        {
            CStatus objCStatus = new CStatus();
            try
            {
                CUser objCUser = new CUser();
                //check if loggedin user session exist then set the value of userid in CUser object (in case of change password at login time)
                if (CurrentUserSession.UserId > 0)
                {
                    objCUser.UserId = CurrentUserSession.UserId;
                }

                //check if user object contains user id then send request for change password
                //else return false status with message.
                if (objCUser.UserId > 0)
                {
                    //set parameters in user object
                    objCUser.OldLogonPassword = pOldPassword;
                    objCUser.LogonPassword = pNewPassword;
                    objCUser.ChangePasswordNextLogon = false;
                    // call to change password function of data layer and get status
                    MUser objMUser = new MUser();
                    objCStatus = objMUser.ChangePassword(AuthenticationContext, objCUser);
                }
                else
                {
                    objCStatus.Success = false;
                    objCStatus.StatusDetails = CAppErrorsConstants.NotValidRequest;
                }
            }
            catch (Exception ex)
            {
                objCStatus.Success = false;
                objCStatus.StatusDetails = ex.Message;
            }
            return Json(objCStatus);
        }

        /// <summary>
        /// this function is used to logout user and remove its entry from application variable
        /// and clear session.
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Logout()
        {
            CStatus objCStatus = new CStatus();
            try
            {
                CUser objCUser = new CUser();
                CUserSession objCUserSession = new CUserSession();
                string SessionState = CheckSessionState();

                //check if session state it is not logout by other then logg it out here.
                if (SessionState != CAppErrorsConstants.NoSession)
                {
                    objCUser.UserId = CurrentUserSession.UserId;

                    objCUserSession.UserId = CurrentUserSession.UserId;

                    objCUserSession.SessionKey = CurrentUserSession.SessionKey;

                    objCUserSession.UserSessionId = CurrentUserSession.UserSessionId;

                    //call to function to remove entry from application level user list.
                    RemoveUserFromApplicationVaraibleList(CurrentUserSession.UserId);

                    // call to logut user function of data layer and get status
                    MUser objMUser = new MUser();
                    objCStatus = objMUser.UserLogout(AuthenticationContext, objCUser);

                    if (objCStatus.Success == true)
                    {

                        MUserSession objMUserSession = new MUserSession();

                        objCStatus = objMUserSession.EndUserSession(AuthenticationContext, ref objCUserSession);

                    }
                }
                else
                {
                    objCStatus.Success = false;
                    objCStatus.StatusDetails = CAppErrorsConstants.NoSession;
                }

            }
            catch (Exception ex)
            {
                objCStatus.Success = false;
                objCStatus.StatusDetails = ex.Message;
            }
            return Json(objCStatus);
        }
        /// <summary>
        /// this funtion is used to remove the entry from application variable of logged in users list.
        /// </summary>
        /// <param name="nUserId">id of user for which have to remove entry</param>
        public void RemoveUserFromApplicationVaraibleList(int nUserId)
        {
            try
            {


                List<CUserSession> oUserSessionList = ApplicationUsers;


                if (oUserSessionList != null && oUserSessionList.Count > 0)
                {
                    List<CUserSession> oSUser = oUserSessionList.Where(u => u.UserId == nUserId).ToList<CUserSession>();
                    //check logout user have information in list or not.
                    if (oSUser.Count > 0)
                    {
                        //EndUserSession(CurrentUserSession);
                        //remove user information from list.
                        foreach (CUserSession ssUser in oSUser)
                        {
                            oUserSessionList.Remove(ssUser);
                        }
                        //update applocation varaible list.
                        ApplicationUsers = oUserSessionList;
                        //call to session clear function to clear session
                        ClearSession();
                    }
                }
            }
            catch
            { }
        }

        public ActionResult GetSidebar()
        {
            ///Organization Drop Down - Begin///

            MOrganization oMOrg = new MOrganization();
            GOrganization oOrgDropDown = new GOrganization();
            List<COrganization> temp_cOrgLst = new List<COrganization>();
            oOrgDropDown.Status = oMOrg.GetOrganizationList(AuthenticationContext, out temp_cOrgLst);

            oOrgDropDown.LstCOrganization.AddRange(temp_cOrgLst);



            ///Organization Drop Down - End///
            return PartialView("~/Views/Shared/_sidemenu.cshtml", oOrgDropDown);
        }

    }
}
